#define _CRT_SECURE_NO_WARNINGS 1
#include "List.h"

LTNode* CreateNode(LTDataType x)
{
    LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));
    if (newNode == NULL)
    {
        perror("malloc");
        exit(-1);
    }
    newNode->data = x;
    newNode->next = NULL;
    newNode->prev = NULL;
    return newNode;
}

void LTPrint(LTNode* plist)
{
    assert(plist);
    printf("head<=>");
    LTNode* cur = plist->next;
    while (cur != plist)
    {
        printf("%d<=>", cur->data);
        cur = cur->next;
    }
    printf("\n");
}

LTNode* LTInit()
{
    LTNode* phead = CreateNode(-1);
    phead->next = phead;
    phead->prev = phead;
    return phead;
}

void LTPushBack(LTNode* phead, LTDataType x)
{
    assert(phead);
    LTNode* newNode = CreateNode(x);
    LTNode* tail = phead->prev;
    tail->next = newNode;
    newNode->prev = tail;
    newNode->next = phead;
    phead->prev = newNode;
}

void LTPushFront(LTNode* phead, LTDataType x)
{
    assert(phead);
    LTNode* newNode = CreateNode(x);
    LTNode* First = phead->next;
    phead->next = newNode;
    newNode->prev = phead;
    newNode->next = First;
    First->prev = newNode;
}

void LTPopBack(LTNode* phead)
{
    assert(phead);
    assert(phead->next != phead);
    LTNode* tail = phead->prev;
    tail->prev->next = phead;
    phead->prev = tail->prev;
    free(tail);
}

void LTPopFront(LTNode* phead)
{
    assert(phead);
    assert(phead->next != phead);
    LTNode* First = phead->next;
    phead->next = First->next;
    First->prev = phead;
    free(First);
    First = NULL;
}

LTNode* LTFind(LTNode* phead, LTDataType x)
{
    assert(phead);
    assert(phead->next != phead);
    LTNode* cur = phead->next;
    while (cur != phead)
    {
        if (cur->data == x)
            return cur;
        cur = cur->next;
    }
    return NULL;
}

void LTInsert(LTNode* pos, LTDataType x)
{
    assert(pos);
    LTNode* newNode = CreateNode(x);
    LTNode* Prev = pos->prev;
    Prev->next = newNode;
    newNode->prev = Prev;
    newNode->next = pos;
    pos->prev = newNode;
}

void LTErase(LTNode* pos)
{
    assert(pos);
    LTNode* Prev = pos->prev;
    LTNode* Next = pos->next;
    Prev->next = Next;
    Next->prev = Prev;
    free(pos);
}

void LTDestroy(LTNode* phead)
{
    assert(phead);
    LTNode* cur = phead->next;
    while (cur != phead)
    {
        LTNode* Next = cur->next;
        free(cur);
        cur = Next;
    }
    free(phead);
}